package top.lenjon.lib.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import top.lenjon.lib.exception.AuthException;
import top.lenjon.lib.model.LoginModel;
import top.lenjon.lib.util.RedisUtil;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 * @Author whz
 * @Date 2020/11/8 22:31
 **/
@Aspect
@Component
public class VerificationAspect {
    @Autowired
    RedisUtil redisUtil;

    private LoginModel loginModel = new LoginModel();

    @Pointcut("execution(public * top.lenjon.lib.controller.*Controller.*(..))  && (!execution(public * top.lenjon.lib.controller.RegisterController.*(..)) && !execution(public * top.lenjon.lib.controller.LoginController.*(..)))")
    public void permission() {
    }


    @Before("permission()")
    public void permissionSetting(JoinPoint joinPoint) {
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        String token = request.getHeader("token");
        if (token == null || !redisUtil.hasKey(token)) {
            throw new AuthException("未登录");
        }
        LoginModel userInfo = (LoginModel) redisUtil.get(token);
        int type = userInfo.getType();
        Class controller = joinPoint.getTarget().getClass();
        String[] args = controller.getName().split("\\.");
        String className = args[args.length - 1];
        if ("AdminController".equals(className) && type < 2) {
            throw new AuthException("没有权限");
        } else if ("BookLogController".equals(className) && type < 1) {
            throw new AuthException("没有权限");
        } else if ("ManagerController".equals(className) && type < 1) {
            throw new AuthException("没有权限");
        }
    }

}


//    @Pointcut("execution(public * top.lenjon.lib.annotation.UserInfo.setInfo())")
//    public void setInfo(){}
//
//    @Around("setInfo()")
//    public Object Info(ProceedingJoinPoint joinPoint) throws Throwable {
//        Object[] object=joinPoint.getArgs();
//        //遍历参数 修改带有需求字段对象的值
//        for (Object obj : object) {
//                System.out.println(obj.toString());
//                Class<?> resultClz = obj.getClass();
//                //获取class里的所有字段  父类字段获取不到
//                Field[] fieldInfo = resultClz.getDeclaredFields();
//                for (Field field : fieldInfo) {
//                    if ("loginModel".equals(field.getName())) {
//                        //成员变量为private,故必须进行此操做
//                        field.setAccessible(true);
//                        //修改前的值
//                        LoginModel fieldValue = (LoginModel) field.get(obj);
//                        //修改后的值
//                        fieldValue.setType(1);
//                        fieldValue.setUsername("sad");
//                        if (fieldValue.getUsername() != null) {
//                            field.set(obj, fieldValue);
//                        }
//                        break;
//                    }
//                }
//
//        }
//        System.out.println(111);
//        return joinPoint.proceed(object);
//    }
//    @Around("@annotation(userInfo)")
//    public Object invoked(ProceedingJoinPoint pjp,UserInfo userInfo) throws Throwable {
//        loginModel.setUsername("aaa");
//        InvocationHandler h = Proxy.getInvocationHandler(userInfo);
//        Field hField = h.getClass().getDeclaredField("memberValues");
//        hField.setAccessible(true);
//        Map<String, Object> memberValues = (Map<String, Object>) hField.get(h);
//        memberValues.put("username", loginModel.getUsername());
//        memberValues.put("type", loginModel.getPassword());
//        return pjp.proceed();
//    }

